bitkeeper revision 1.1159.27.1 (411ce22fF0PE2whpAPrucFCnOwpOIw)
authoriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>
Fri, 13 Aug 2004 15:45:51 +0000 (15:45 +0000)
committeriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>
Fri, 13 Aug 2004 15:45:51 +0000 (15:45 +0000)
save/restore for linux 2.6 (not quite there yet)

linux-2.6.7-xen-sparse/arch/xen/i386/kernel/irq.c
linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c
tools/libxc/xc_linux_restore.c
tools/libxc/xc_linux_save.c
xen/arch/x86/x86_32/mm.c
xen/include/asm-x86/mm.h

index 6698c8ca5f27e588b8c871823bc4254fe41fb63d..b79c689474738ad2e1c3fbc537b7c9dc2f6ad892 100644 (file)
@@ -694,6 +694,7 @@ void free_irq(unsigned int irq, void *dev_id)
        p = &desc->action;
        for (;;) {
                struct irqaction * action = *p;
+
                if (action) {
                        struct irqaction **pp = p;
                        p = &action->next;
@@ -710,7 +711,10 @@ void free_irq(unsigned int irq, void *dev_id)
 
                        /* Wait to make sure it's not being used on another CPU */
                        synchronize_irq(irq);
-                       kfree(action);
+
+#define SA_STATIC_ACTION 0x01000000 /* Is it our duty to free the action? */
+                       if (!(action->flags & SA_STATIC_ACTION))
+                               kfree(action);
                        return;
                }
                printk("Trying to free free IRQ%d\n",irq);
index d3679ef76bb91fe6c1202ae29cbf2d701575a841..a3d46cb23197c7361ed93f7ca71e32f29a208dd1 100644 (file)
@@ -107,7 +107,11 @@ static void __do_suspend(void)
 
     memcpy(&start_info, &suspend_record->resume_info, sizeof(start_info));
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+    set_fixmap_ma(FIX_SHARED_INFO, start_info.shared_info);
+#else
     set_fixmap(FIX_SHARED_INFO, start_info.shared_info);
+#endif
 
     HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
 
@@ -134,7 +138,6 @@ static void __do_suspend(void)
 
     __sti();
 
-
  out:
     if ( suspend_record != NULL )
         free_page((unsigned long)suspend_record);
index 62050c83eba91bf87a7141b6934f939b76b66a5c..5ccbb6e2256cdfc3d7a90edd7f726213099874e8 100644 (file)
@@ -112,7 +112,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
     unsigned long *region_mfn = NULL;
 
     /* A temporary mapping, and a copy, of one frame of guest memory. */
-    unsigned long *ppage;
+    unsigned long *ppage = NULL;
 
     /* A copy of the pfn-to-mfn table frame list. */
     unsigned long pfn_to_mfn_frame_list[1024];
@@ -530,6 +530,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt)
         xcio_error(ioctxt, "GDT entry count out of range");
         goto out;
     }
+
     for ( i = 0; i < ctxt.gdt_ents; i += 512 )
     {
         pfn = ctxt.gdt_frames[i];
index c2482ef2b17dddb0f811b2c93a1c38a1c64be31f..1d4a05425745b1c9001858eb4d8bd2a23f43657e 100644 (file)
@@ -320,7 +320,7 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt)
     unsigned long page[1024];
 
     /* A copy of the pfn-to-mfn table frame list. */
-    unsigned long *live_pfn_to_mfn_frame_list;
+    unsigned long *live_pfn_to_mfn_frame_list = NULL;
     unsigned long pfn_to_mfn_frame_list[1024];
 
     /* Live mapping of the table mapping each PFN to its current MFN. */
@@ -330,13 +330,13 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt)
     unsigned long mfn_to_pfn_table_start_mfn;
     
     /* Live mapping of shared info structure */
-    shared_info_t *live_shinfo;
+    shared_info_t *live_shinfo = NULL;
 
     /* base of the region in which domain memory is mapped */
     unsigned char *region_base = NULL;
 
     /* A temporary mapping, and a copy, of the guest's suspend record. */
-    suspend_record_t *p_srec;
+    suspend_record_t *p_srec = NULL;
 
     /* number of pages we're dealing with */
     unsigned long nr_pfns;
@@ -679,6 +679,7 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt)
             for ( j = 0; j < batch; j++ ){
                 if ( (pfn_type[j] & LTAB_MASK) == XTAB ){
                     DDPRINTF("type fail: page %i mfn %08lx\n",j,pfn_type[j]);
+printf("type fail: page %i mfn %08lx\n",j,pfn_type[j]);
                     continue;
                 }
   
@@ -829,7 +830,7 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt)
                    goto out;
                }
 
-               printf("SUSPPPPPPPP flags %08lx shinfo %08lx eip %08lx esi %08lx\n", 
+               printf("SUSPEND flags %08lx shinfo %08lx eip %08lx esi %08lx\n", 
                       op.u.getdomaininfo.flags, op.u.getdomaininfo.shared_info_frame,
                       ctxt.cpu_ctxt.eip, ctxt.cpu_ctxt.esi );
 
@@ -894,9 +895,10 @@ printf("nrpfns according to suspend record is %ld\n", p_srec->nr_pfns );
         xcio_error(ioctxt, "Suspend record is not in range of pseudophys map");
         goto out;
     }
-       
+
     /* Canonicalise each GDT frame number. */
     for ( i = 0; i < ctxt.gdt_ents; i += 512 ) {
+       ctxt.gdt_frames[i], live_mfn_to_pfn_table[ctxt.gdt_frames[i]]);
         if ( !translate_mfn_to_pfn(&ctxt.gdt_frames[i]) ) {
             xcio_error(ioctxt, "GDT frame is not in range of pseudophys map");
             goto out;
@@ -916,9 +918,16 @@ printf("nrpfns according to suspend record is %ld\n", p_srec->nr_pfns );
         xcio_error(ioctxt, "Error when writing to state file (1)");
         goto out;
     }
-    munmap(live_shinfo, PAGE_SIZE);
+
 printf("Everything saved OK!\n");
  out:
+
+    if ( live_shinfo )          munmap(live_shinfo, PAGE_SIZE);
+    if ( p_srec )               munmap(p_srec, sizeof(*p_srec));
+    if ( live_pfn_to_mfn_frame_list ) munmap(live_pfn_to_mfn_frame_list, PAGE_SIZE);
+    if ( live_pfn_to_mfn_table ) munmap(live_pfn_to_mfn_table, nr_pfns*4 );
+    if ( live_mfn_to_pfn_table ) munmap(live_mfn_to_pfn_table, PAGE_SIZE*1024 );
+
     if ( pfn_type != NULL ) free(pfn_type);
     DPRINTF("Save exit rc=%d\n",rc);
     return !!rc;
index a38cb6b0ade5e6d6a7e669c3369cd432df5da2b6..6c5b26f87c5d7548656312bdc75c4bd1b5643a41 100644 (file)
@@ -262,6 +262,10 @@ long set_gdt(struct domain *d,
     int i, nr_pages = (entries + 511) / 512;
     struct desc_struct *vgdt;
 
+    vgdt = map_domain_mem(frames[0] << PAGE_SHIFT);
+    memset( vgdt + FIRST_RESERVED_GDT_ENTRY, 0,            
+           NR_RESERVED_GDT_ENTRIES*8);
+
     /* Check the new GDT. */
     for ( i = 0; i < nr_pages; i++ )
     {
@@ -272,7 +276,6 @@ long set_gdt(struct domain *d,
     }
 
     /* Copy reserved GDT entries to the new GDT. */
-    vgdt = map_domain_mem(frames[0] << PAGE_SHIFT);
     memcpy(vgdt + FIRST_RESERVED_GDT_ENTRY, 
            gdt_table + FIRST_RESERVED_GDT_ENTRY, 
            NR_RESERVED_GDT_ENTRIES*8);
index 7ee6b24bffc5393b900f5198820f1707c647d96e..cc68ce083e2bc9c723aae8ad28f3fa4b898d161e 100644 (file)
@@ -249,8 +249,10 @@ static inline int get_page_type(struct pfn_info *page, u32 type)
         /* Try to validate page type; drop the new reference on failure. */
         if ( unlikely(!alloc_page_type(page, type)) )
         {
-            DPRINTK("Error while validating pfn %08lx for type %08x\n",
-                    page_to_pfn(page), type);
+            DPRINTK("Error while validating pfn %08lx for type %08x. caf=%08x taf=%08x\n",
+                    page_to_pfn(page), type,
+                   page->u.inuse.count_info,
+                   page->u.inuse.type_info);
             put_page_type(page);
             return 0;
         }